package com.pinyougou.search.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.pojo.TbItem;
import com.pinyougou.pojo.TbSpecification;
import com.pinyougou.search.service.ItemSearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.*;
import org.springframework.data.solr.core.query.result.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service(timeout = 10000)
public class ItemSearchServiceImpl implements ItemSearchService {

    @Autowired
    private SolrTemplate solrTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public Map search(Map searchMap) {
        Map map = new HashMap();

        //搜索关键字空格处理
        String keywords = (String) searchMap.get("keywords");
        System.out.println(keywords);
        searchMap.put("keywords",keywords.replace(" ",""));

        //1.按关键字查询(高亮显示)
        map.putAll(searchList(searchMap));

        //2.根据关键字分组查询商品分类
        List categoryList = searchCategoryList(searchMap);
        map.put("categoryList",categoryList);

        //3.查询品牌和规格列表
        String categoryName = (String) searchMap.get("category");//获取商品分类名
        if (!"".equals(categoryName)){ //如果点击了商品分类,则展示对应分类的品牌和规格列表
            map.putAll(searchBrandAndSpecList(categoryName));
        }else {
            if (categoryList.size() > 0){ //如果没点击商品分类,默认展示第一个分类的品牌和规格列表
                map.putAll(searchBrandAndSpecList((String) categoryList.get(0)));
            }
        }
        return map;
    }

    /*
    导入数据到索引库
     */
    @Override
    public void importList(List list) {
        solrTemplate.saveBeans(list);
        solrTemplate.commit();
    }


    /**
     *删除数据
     * @param goodsIdList
     */
    @Override
    public void deleteByGoodsIds(List goodsIdList) {
        System.out.println("删除商品ID"+goodsIdList);
        Query query=new SimpleQuery();
        Criteria criteria=new Criteria("item_goodsId").in(goodsIdList);
        query.addCriteria(criteria);
        solrTemplate.delete(query);
        solrTemplate.commit();
    }



    /**
     * 按关键字查询(高亮显示)
     * 创建私有方法，用于返回查询列表的结果（高亮显示）
     * 根据关键字搜索列表
     *
     * @param searchMap
     * @return
     */
    private Map searchList(Map searchMap) {
        HashMap map = new HashMap();

        SimpleHighlightQuery query = new SimpleHighlightQuery();

        //构建高亮选项对象
        HighlightOptions highlightOptions = new HighlightOptions().addField("item_title");//设置高亮的域为 item_title
        highlightOptions.setSimplePrefix("<em style='color:red'>");//高亮前缀
        highlightOptions.setSimplePostfix("</em>"); //高亮后缀
        query.setHighlightOptions(highlightOptions); //设置高亮选项

        //1.1 ***按照关键字查询***
        Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));
        query.addCriteria(criteria);

        //1.2 ***按商品分类过滤查询***
        if (!"".equals(searchMap.get("category"))){

            Criteria filterCriteria = new Criteria("item_category").is(searchMap.get("category"));
            SimpleFilterQuery filterQuery = new SimpleFilterQuery(filterCriteria);
            query.addFilterQuery(filterQuery);
        }

        //1.3 ***按品牌过滤查询***
        if(!"".equals(searchMap.get("brand"))){
            Criteria filterCriteria=new Criteria("item_brand").is(searchMap.get("brand"));
            FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
            query.addFilterQuery(filterQuery);
        }

        //1.4 ***规格过滤查询***
        if (searchMap.get("spec")!=null){
            Map<String,String> specMap = (Map) searchMap.get("spec");
            for (String key : specMap.keySet()) {
                Criteria filterCriteria = new Criteria("item_spec_"+key).is(specMap.get(key));
                SimpleFilterQuery filterQuery = new SimpleFilterQuery(filterCriteria);
                query.addFilterQuery(filterQuery);
            }
        }

        //1.5 ***按价格过滤查询***
        if (!"".equals(searchMap.get("price"))){ //如果价格区间起点不等于0
            String[] price= ((String) searchMap.get("price")).split("-");
            if (!price[0].equals("0")){

                Criteria filterCriteria = new Criteria("item_price").greaterThan(price[0]);
                SimpleFilterQuery filterQuery = new SimpleFilterQuery(filterCriteria);
                query.addFilterQuery(filterQuery);
            }

            if (!price[1].equals("*")){ //如果价格区间终点不等于*
                Criteria filterCriteria = new Criteria("item_price").lessThan(price[1]);
                SimpleFilterQuery filterQuery = new SimpleFilterQuery(filterCriteria);
                query.addFilterQuery(filterQuery);
            }

        }

        //1.6 ***分页查询***
        Integer pageNo = (Integer) searchMap.get("pageNo"); //当前页
        if (pageNo ==null){ //如果前台传来的当前页为空,设默认为1
            pageNo =1;
        }

        Integer pageSize = (Integer) searchMap.get("pageSize");//每页显示的记录数
        if (pageSize == null){//如果前台传来的pageSize为空,设默认为10
            pageSize = 10;
        }

        query.setOffset((pageNo-1)*pageSize); //从第几天记录开始查询
        query.setRows(pageSize);

        //1.7 ***排序***
        String sortValue = (String) searchMap.get("sort");//ASC 或 DESC
        String sortField = (String) searchMap.get("sortField");//获取排序字段
        if (sortValue != null && !sortValue.equals("")){
            if (sortValue.equals("ASC")){ //升序
                Sort sort = new Sort(Sort.Direction.ASC,"item_"+sortField);
                query.addSort(sort);
            }

            if (sortValue.equals("DESC")){ //降序
                Sort sort = new Sort(Sort.Direction.DESC,"item_"+sortField);
                query.addSort(sort);
            }
        }


        //**********获取高亮结果集***********
        //高亮页对象
        HighlightPage<TbItem> page = solrTemplate.queryForHighlightPage(query, TbItem.class);

        List<HighlightEntry<TbItem>> entryList = page.getHighlighted(); //高亮入口集合(每条记录的高亮入口)
        for (HighlightEntry<TbItem> entry : entryList) { //循环高亮入口集合

            List<HighlightEntry.Highlight> highlightList = entry.getHighlights();//获取高亮列表(高亮域的个数)
            if (highlightList.size() > 0) {
                for (HighlightEntry.Highlight highlight : highlightList) {

                    List<String> snipplets = highlight.getSnipplets();//每个域可能有多个值
                    if (snipplets.size() > 0) {
                        for (String snipplet : snipplets) {

                            TbItem tbItem = entry.getEntity();//获取原实体类
                            tbItem.setTitle(snipplet);//设置高亮结果
                        }
                    }
                }
            }
        }

        map.put("rows", page.getContent());

        map.put("totalPages",page.getTotalPages());//返回总页数
        map.put("total",page.getTotalElements());//返回总记录数
        return map;
    }

    /**
     * 分组查询分类列表
     * @param searchMap
     * @return
     */
    private List searchCategoryList(Map searchMap){
        List<String> list = new ArrayList<String>();

        Query query = new SimpleQuery();
        //按照关键字查询
        Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));
        query.addCriteria(criteria);

        //设置分组选项
        GroupOptions groupOptions = new GroupOptions().addGroupByField("item_category");
        query.setGroupOptions(groupOptions);

        //得到分组页
        GroupPage<TbItem> page = solrTemplate.queryForGroupPage(query, TbItem.class);

        //根据列得到分组结果集
        GroupResult<TbItem> groupResult = page.getGroupResult("item_category");

        //得到分组结果入口页
        Page<GroupEntry<TbItem>> groupEntries = groupResult.getGroupEntries();

        //得到分组入口集合
        List<GroupEntry<TbItem>> content = groupEntries.getContent();

        for (GroupEntry<TbItem> entry : content) {
            list.add(entry.getGroupValue());//将分组结果的名称分装到返回值中
        }
        return list;
    }

    /**
     * 根据商品分类名称查询品牌和规格列表
     * @param category  分类名称
     * @return
     */
    private Map searchBrandAndSpecList(String category){
        HashMap<String, Object> map = new HashMap<>();

        Long typeId= (Long) redisTemplate.boundHashOps("itemCat").get(category); //获取模板id

        if (typeId != null){
            //根据模板id查询品牌列表
            List<TbBrand> brandList = (List<TbBrand>) redisTemplate.boundHashOps("brandList").get(typeId);
            map.put("brandList",brandList);

           // 根据模板id查询规格列表
            List<TbSpecification> specList = (List<TbSpecification>) redisTemplate.boundHashOps("specList").get(typeId);
            map.put("specList",specList);
        }
        return map;
    }
}
